/*
 * anima/cpu.hh - Generic CPU interface.
 * Copyright (C) 2007  Mikhail Vorozhtsov
 * See the LICENSE section of the README file for details.
 */

/* $Id$ */

#ifndef HEADER_ANIMA_CPU_HH
#define HEADER_ANIMA_CPU_HH

#include ANIMA_ARCH_HEADER (cpu.hh)
#include HEADER (anima,object.hh)
#include HEADER (LIBBST_PREFIX,parent_node.hh)
#include HEADER (LIBBST_PREFIX,avl_tree.hh)

START_NAMESPACE (anima)

class pdb;

struct fwd_cpu_t : public object_t, public ANIMA_ARCH::cpu_t
{
public:
  enum state_t
  {
    STATE_FRESH,
    STATE_SCHEDULING,
    STATE_IDLE,
    STATE_RUNNING
  };

protected:
  id_t id;
  thread_t *threads;
  thread_t *cur_thread;
  thread_t *scheduler;
  thread_t *backup_scheduler;
  state_t state;

public:
  LIBBST_NS::basic_avl_node_t<LIBBST_NS::basic_parent_next_node_t> __node;
};

struct cpu_t : public fwd_cpu_t
{
  friend class ANIMA_ARCH::cpu_t;
  friend class pdb;

private:
  static LIBBST_NS::avl_tree_t<
           LIBBST_NS::parent_next_node_t<
             cpu_t, LIBBST_NS::basic_avl_node_t<
                      LIBBST_NS::basic_parent_next_node_t>,
             offsetof (fwd_cpu_t, __node)>,
           LIBBST_NS::basic_min_tree_t, LIBBST_NS::min_glue_t> cpus;

private:
  static bool page_used_p (u64_t addr);

public:
  static bool check_feats ();
  static bool init ();

public:
  static id_t get_current_id ();
  static cpu_ref_t get (id_t id);

public:
  static cpu_t *create (id_t id);

private:
  bool init_instance ();

public:
  void attach ();
  void detach ();

public:
  void set_scheduler (thread_t *thread);
  void add (thread_t *thread);

private:
  void install (thread_t *thread);

public:
  INLINE
  bool
  operator== (id_t id) const
  {
    return this->id == id;
  }

  INLINE
  bool
  operator< (id_t id) const
  {
    return this->id < id;
  }

  INLINE
  bool
  operator== (const cpu_t &cpu) const
  {
    return id == cpu.id;
  }

  INLINE
  bool
  operator< (const cpu_t &cpu) const
  {
    return id < cpu.id;
  }
};

END_NAMESPACE

#endif /* HEADER_ANIMA_CPU_HH */

